package com.lyy.king.tools.service.captcha.impl;

import com.lyy.king.common.core.constant.RedisPrefixConstances;
import com.lyy.king.common.redis.service.RedisService;
import com.lyy.king.common.utils.constant.Constants;
import com.lyy.king.common.utils.exception.BizException;
import com.lyy.king.common.utils.utils.uuid.IdUtils;
import com.lyy.king.tools.model.response.CaptchaResponse;
import com.lyy.king.tools.request.CheckCaptchaRequest;
import com.lyy.king.tools.service.captcha.CaptchaService;
import com.google.code.kaptcha.Producer;
import org.bouncycastle.util.encoders.Base64;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.FastByteArrayOutputStream;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * @ClassDescription:
 * @JdkVersion: 1.8
 * @Author: cdx
 * @Created: 2024/1/7 14:35
 */
@Service
public class CaptchaServiceImpl implements CaptchaService {
    // 字母验证码
    @Resource(name = "captchaProducer")
    Producer captchaProducer;

    // 数学计算验证码
    @Resource(name = "captchaProducerMath")
    Producer captchaProducerMath;

    @Autowired
    RedisService redisService;

    @Override
    public CaptchaResponse captchaImage() {
        CaptchaResponse captcha = new CaptchaResponse();
        // TODO 验证码开关，目前固定开启，后期改造为配置
        captcha.setCaptchaOnOff(true);
        // 生成验证码缓存key
        String uuid = IdUtils.simpleUUID();
        String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid;
        // 验证码类型，目前固定写为math，
        String captchaType = "math";
        String capStr = null, code = null;
        BufferedImage image = null;
        // 生成验证码
        if ("math".equals(captchaType)) {
            // 计算验证码
            String capText = captchaProducerMath.createText();
            capStr = capText.substring(0, capText.lastIndexOf("@"));
            code = capText.substring(capText.lastIndexOf("@") + 1);
            image = captchaProducerMath.createImage(capStr);
        } else if ("char".equals(captchaType)) {
            // 字符验证码
            capStr = code = captchaProducer.createText();
            image = captchaProducer.createImage(capStr);
        }

        // 加入缓存，5分钟过期
        redisService.setCacheObject(RedisPrefixConstances.PREFIX_CAPTCHA + uuid, code, RedisPrefixConstances.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);

        // 转换流信息写出
        FastByteArrayOutputStream os = new FastByteArrayOutputStream();
        try {
            ImageIO.write(image, "jpg", os);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        captcha.setUuid(uuid);
        captcha.setImg(Base64.toBase64String(os.toByteArray()));
        return captcha;
    }

    @Override
    public Boolean checkCaptcha(CheckCaptchaRequest request) {
        String redisKey = RedisPrefixConstances.PREFIX_CAPTCHA + request.getUuid();
        // 获取验证码缓存
        String cacheCode = redisService.getCacheObject(redisKey);
        // 删除验证码缓存
        redisService.deleteObject(redisKey);
        // 检查验证码
        BizException.check(cacheCode != null,"验证码失效");
        BizException.check(cacheCode.equals(request.getCode()),"验证码错误");

        return true;
    }
}
